package com.ken.astroboy.listener;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.web.socket.TextMessage;

import com.google.gson.Gson;
import com.ken.astroboy.core.InMemoryStorage;
import com.ken.astroboy.logic.LogicProcess;
import com.ken.astroboy.service.WxService;
import com.ken.astroboy.util.Exceptions;
import com.ken.astroboy.websocket.SpringWebSocketHandler;

public class WechatListener extends Thread {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Bean//这个注解会从Spring容器拿出Bean
    public SpringWebSocketHandler wsHandler() {
        return new SpringWebSocketHandler();
    }

    public WechatListener(String name) {
        super(name);
    }


    @Override
    public void run() {

        logger.info("进入消息监听线程 ...");

        InMemoryStorage.keepListening = true;

        Map<String, String> map = new HashMap<>();                       
        Gson gson = new Gson();
        
        boolean isLogin = true;
        int reInitWxTimes = 0;
        int errorTimes = 0;


        while(errorTimes < 5){
            if(!WxService.chooseSyncLine()){
                errorTimes++;
                logger.info("累计errorTimes：" + errorTimes);
            }else{
                break;
            }
        }

        if(errorTimes >= 5){

            map.put("msg", "小木木登录时选择同步线路失败");
            map.put("code", "903");	     
            
            LogicProcess.initDataInWxServiceAndInMemoryStorage();
            
            wsHandler().sendMessageToUser("default-system", new TextMessage(gson.toJson(map)));

            return;
        }

        //机器人初始化就绪
        errorTimes = 0;

        map.put("msg", "小木木登录成功");
        map.put("code", "202");

        InMemoryStorage.isRobotOnline = true;
        InMemoryStorage.isRobotHealthy = true;

        wsHandler().sendMessageToUser("default-system", new TextMessage(gson.toJson(map)));


        while(InMemoryStorage.keepListening){						

            logger.info("消息监听中...");

            if(errorTimes >= 5){
                errorTimes = 0;
                logger.info("累计errorTimes次数到，开始reInitWx()");	

                if(reInitWxTimes < 5){
                                     
                    if(InMemoryStorage.isRobotHealthy){
                        map.put("msg", "小木木现在碰到点麻烦，正在尝试解决...");
                        map.put("code", "401");

                        wsHandler().sendMessageToUser("default-system", new TextMessage(gson.toJson(map)));

                        InMemoryStorage.isRobotHealthy = false;                            
                    }
                    
                    LogicProcess.reInitWx();
                    reInitWxTimes++;
                    logger.info("累计reInitWxTimes：" + reInitWxTimes);	
                }else{
                    logger.info("累计reInitWxTimes次数过多，退出消息监听线程");

                    map.put("msg", "运行中出现不可恢复的错误，请重新登录机器人");
                    map.put("code", "904");
                    InMemoryStorage.isRobotOnline = false;
                    InMemoryStorage.isRobotHealthy = false;
                    LogicProcess.initDataInWxServiceAndInMemoryStorage();
                    
                    wsHandler().sendMessageToUser("default-system", new TextMessage(gson.toJson(map)));

                    break;
                }
            }						

            int retcode = -1;
            int selector = -1;

            try{
                int[] arr = WxService.syncCheck();
                retcode = arr[0];
                selector = arr[1];

            }catch(Exception e){
                logger.info("出错-syncCheck出现异常");
                logger.info(Exceptions.getExceptionDetail(e));

                errorTimes++;
                logger.info("累计errorTimes：" + errorTimes);		

                continue;
            }

            logger.info("retcode={}, selector={}", retcode, selector);

            try{
                switch(retcode){
                case 0:							
                    switch(selector){
                    case 0: //Idle
                        
                        if(!InMemoryStorage.isRobotHealthy){
                            
                            if(InMemoryStorage.keepListening){
                                map.put("msg", "机器人现在很健康");
                                map.put("code", "203");
        
                                wsHandler().sendMessageToUser("default-system", new TextMessage(gson.toJson(map)));                                
                            }                       
    
                            InMemoryStorage.isRobotHealthy = true;                            
                        }
                        reInitWxTimes = 0;
                        break;

                    case 2:	//有消息到要处理
                    case 4: //通讯录更新
                    case 6: //可能是红包(经过测试，添加好友成功也返回6)
                        logger.info("收到消息，开始处理...");

                        if(!InMemoryStorage.isRobotHealthy){
                            if(InMemoryStorage.keepListening){
                                map.put("msg", "机器人现在很健康");
                                map.put("code", "203");
        
                                wsHandler().sendMessageToUser("default-system", new TextMessage(gson.toJson(map)));                                
                            }      
                            InMemoryStorage.isRobotHealthy = true;                            
                        }
                        reInitWxTimes = 0;

                        LogicProcess.handleSyncResponse( WxService.webWxSync() );
                        break;

                    case 3: //未知情况													
                    case 7: //在手机上操作了微信
                        WxService.webWxSync();
                        break;

                    default:
                        //未知情况
                        WxService.webWxSync();
                        errorTimes++;
                        logger.info("累计errorTimes：" + errorTimes);		
                        break;
                    }

                    break;

                case 1100:
                case 1101:
                    
                    InMemoryStorage.isRobotOnline = false;
                    InMemoryStorage.isRobotHealthy = false;
                    
                    if(!LogicProcess.removeAllJobs()){
                        logger.info("删除全部定时任务失败");
                        
                        //todo:是否需要重启服务器？
                    }
                    
                    logger.info("删除全部定时任务");
                    
                    //QuartzManager.shutdownScheduler();
                    
                    LogicProcess.initDataInWxServiceAndInMemoryStorage();
                    
                    isLogin = false;

                    map.put("msg", "您登出了微信或是在其他地方登陆了Web版微信，请重新登录机器人");
                    map.put("code", "905");
                    wsHandler().sendMessageToUser("default-system", new TextMessage(gson.toJson(map)));

                    break;

                default:
                    //未知情况
                    WxService.webWxSync();
                    errorTimes++;
                    logger.info("累计errorTimes：" + errorTimes);			
                    break;
                }

            }catch(Exception e){
                logger.info("出错 - 处理syncCheck返回值时出现异常");
                logger.info(Exceptions.getExceptionDetail(e));
                errorTimes++;
                logger.info("累计errorTimes：" + errorTimes);	

            }

            if(isLogin){
                try {
                    Thread.sleep(1800);
                } catch (InterruptedException e) {
                    logger.info("出错-Thread.sleep出现异常");
                    logger.info(Exceptions.getExceptionDetail(e));
    
                }                
            }else{
                
                break;
            }
        }		
        
        logger.info("退出消息监听线程");
        
    }
}
